package cn.com.dingtek.genius.manager.server.web.controller;

import cn.com.dingtek.genius.manager.server.event.UserOperateEvent;
import cn.com.dingtek.genius.manager.server.repository.db.entity.DeviceBase;
import cn.com.dingtek.genius.manager.server.service.DeviceUnbindService;
import cn.com.dingtek.genius.manager.server.support.sam.SecurityContextHolder;
import cn.com.dingtek.genius.manager.server.support.sam.annotation.AssertAuth;
import cn.com.dingtek.genius.manager.server.utils.IPUtil;
import cn.com.dingtek.genius.manager.server.web.Result;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xuxueli.poi.excel.ExcelImportUtil;
import com.xuxueli.poi.excel.annotation.ExcelField;
import com.xuxueli.poi.excel.annotation.ExcelSheet;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/device/unbind")
public class DeviceUnbindController {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @Autowired
    private DeviceUnbindService deviceUnbindService;

    @AssertAuth
    @PostMapping("/list")
    public Result list(@RequestBody JSONObject json) {
        int currentPage = json.getInteger("current_page") == null ? 0 : json.getInteger("current_page");
        int pageSize = json.getInteger("page_size") == null ? 10 : json.getInteger("page_size");
        DeviceBase param = json.getObject("search_param", DeviceBase.class);
        return Result.ok(deviceUnbindService.list(param, currentPage, pageSize));
    }

    @AssertAuth
    @GetMapping("/info/{id}")
    public Result info(@PathVariable("id") Long id) {
        return Result.ok(deviceUnbindService.info(id));
    }

    @AssertAuth
    @PostMapping("/add")
    public Result add(@RequestBody JSONObject json, HttpServletRequest request) {
        long userId = SecurityContextHolder.getContext().getToken().getUserId();
        String account = SecurityContextHolder.getContext().getToken().getAccount();

        DeviceBase param = json.toJavaObject(DeviceBase.class);
        try {
            deviceUnbindService.add(param, false, account, DateTime.now().toDate());
            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("注册设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(true)
            );
        } catch (Exception e) {
            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("注册设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(false)
            );
            throw e;
        }
        return Result.ok();
    }


    @AssertAuth
    @PostMapping("/add/batch")
    public Result addBatch(@RequestParam MultipartFile file, @RequestParam Integer deviceType,
                           @RequestParam Integer deviceSocket, @RequestParam String waveLength,
                           @RequestParam Integer platformType, @RequestParam String companyId,
                           @RequestParam Boolean toWeb,
                           HttpServletRequest request) throws IOException {
        long userId = SecurityContextHolder.getContext().getToken().getUserId();
        String account = SecurityContextHolder.getContext().getToken().getAccount();

        try {

            List<Object> imeiList = ExcelImportUtil.importExcel(file.getInputStream(), DeviceImei.class);

            Long companyId_L = null;
            if (StringUtils.isNumeric(companyId)) {
                companyId_L = Long.valueOf(companyId);
            }

            DeviceBase param = DeviceBase.builder()
                    .deviceType(deviceType)
                    .deviceSocket(deviceSocket)
                    .waveLength(waveLength)
                    .platformType(platformType)
                    .companyId(companyId_L)
                    .build();

            Date now = DateTime.now().toDate();
            for (Object imei : imeiList) {
                DeviceUnbindController.DeviceImei deviceImei = (DeviceUnbindController.DeviceImei) imei;
                param.setImei(deviceImei.getImei());
                deviceUnbindService.add(param, toWeb, account, now);
            }

            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("批量注册设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(true)
            );
        } catch (Exception e) {
            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("批量注册设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(false)
            );
            throw e;
        }

        return Result.ok();
    }

    @ExcelSheet(name = "设备列表", headColor = HSSFColor.HSSFColorPredefined.LIGHT_GREEN)
    public static class DeviceImei {
        @ExcelField(name = "设备imei")
        private String imei;

        public String getImei() {
            return imei;
        }

        public void setImei(String imei) {
            this.imei = imei;
        }
    }


    @AssertAuth
    @GetMapping("/remove/{id}")
    public Result remove(@PathVariable("id") Long id, HttpServletRequest request) {
        long userId = SecurityContextHolder.getContext().getToken().getUserId();
        String account = SecurityContextHolder.getContext().getToken().getAccount();

        try {
            deviceUnbindService.remove(id);
            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("移除设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(true)
            );
        } catch (Exception e) {
            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("移除设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(false)
            );
            throw e;
        }
        return Result.ok();
    }

    @AssertAuth
    @PostMapping("/update")
    public Result update(@RequestBody JSONObject json, HttpServletRequest request) {
        long userId = SecurityContextHolder.getContext().getToken().getUserId();
        String account = SecurityContextHolder.getContext().getToken().getAccount();

        DeviceBase param = json.toJavaObject(DeviceBase.class);

        try {
            deviceUnbindService.update(param, account, DateTime.now().toDate());
            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("更新设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(true)
            );
        } catch (Exception e) {
            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("更新设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(false)
            );
            throw e;
        }
        return Result.ok();
    }

    @AssertAuth
    @PostMapping("/allocation")
    public Result allocation(@RequestBody JSONObject json, HttpServletRequest request) {
        long userId = SecurityContextHolder.getContext().getToken().getUserId();
        String account = SecurityContextHolder.getContext().getToken().getAccount();

        Long deviceId = json.getLong("id");
        Long companyId = json.getLong("companyId");
        Boolean toWeb = json.getBoolean("toWeb");

        try {
            deviceUnbindService.allocation(deviceId, companyId, toWeb, account, DateTime.now().toDate());
            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("分配设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(true)
            );
        } catch (Exception e) {
            applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                    .setUserId(userId)
                    .setAccountName(account)
                    .setOperateModule("设备库存")
                    .setOperateDesc("分配设备")
                    .setOperateIp(IPUtil.getIpAddress(request))
                    .setLogState(false)
            );
            throw e;
        }
        return Result.ok();
    }

    @AssertAuth
    @PostMapping("/allocation/batch")
    public Result allocationBatch(@RequestBody JSONObject json, HttpServletRequest request) {
        long userId = SecurityContextHolder.getContext().getToken().getUserId();
        String account = SecurityContextHolder.getContext().getToken().getAccount();

        JSONArray ids = json.getJSONArray("ids");
        List<Long> deviceIds = ids.toJavaList(Long.class);
        if (deviceIds == null || deviceIds.isEmpty()) {
            return Result.ok();
        }

        Long companyId = json.getLong("companyId");
        Boolean toWeb = json.getBoolean("toWeb");

        for (Long deviceId : deviceIds) {
            try {
                deviceUnbindService.allocation(deviceId, companyId, toWeb, account, DateTime.now().toDate());
                applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                        .setUserId(userId)
                        .setAccountName(account)
                        .setOperateModule("设备库存")
                        .setOperateDesc("分配设备")
                        .setOperateIp(IPUtil.getIpAddress(request))
                        .setLogState(true)
                );
            } catch (Exception e) {
                applicationEventPublisher.publishEvent(new UserOperateEvent(this)
                        .setUserId(userId)
                        .setAccountName(account)
                        .setOperateModule("设备库存")
                        .setOperateDesc("分配设备")
                        .setOperateIp(IPUtil.getIpAddress(request))
                        .setLogState(false)
                );
                throw e;
            }
        }

        return Result.ok();
    }
}
